package com.example.elderlycare.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.elderlycare.dao.entity.*;
import com.example.elderlycare.dao.mapper.*;
import com.example.elderlycare.service.BigScreenService;
import com.example.elderlycare.service.entity.BigScreenResponseBody;
import com.example.elderlycare.utils.FormatDate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class BigScreenServiceImpl implements BigScreenService {

    @Resource
    NursingHomeMapper nursingHomeMapper;

    @Resource
    BerthMapper berthMapper;

    @Resource
    EmployeeMapper employeeMapper;

    @Resource
    EquipmentMapper equipmentMapper;

    @Resource
    ComplaintMapper complaintMapper;

    @Resource
    RetardRecordMapper retardRecordMapper;

    @Resource
    CheckRecordMapper checkRecordMapper;

    @Resource
    ConsultMapper consultMapper;

    @Resource
    OutRecordMapper outRecordMapper;

    @Resource
    VisitMapper visitMapper;

    @Resource
    CommonMapper commonMapper;

    @Override
    public BigScreenResponseBody getBigScreenData() {
        String nowDate = FormatDate.getFormatDate(new Date());
        /* 获取当前日期前一周的日期 */
        String weekAgo = getWeekAgoDate();
        /* 获取当前日期前一个月的日期 */
        String monthAgo = getMonthAgoDate();

        /* 日期范围查询参数 */
        Map<String, Object> daily = new HashMap<>(4);
        daily.put("startDate", nowDate);
        daily.put("endDate", nowDate);
        daily.put("startTime", nowDate);
        daily.put("endTime", nowDate);
        Map<String, Object> weekly = new HashMap<>(4);
        weekly.put("startDate", weekAgo);
        weekly.put("endDate", nowDate);
        weekly.put("startTime", weekAgo);
        weekly.put("endTime", nowDate);
        Map<String, Object> monthly = new HashMap<>(4);
        monthly.put("startDate", monthAgo);
        monthly.put("endDate", nowDate);
        monthly.put("startTime", monthAgo);
        monthly.put("endTime", nowDate);

        /*获取学历字典数据*/
        QueryWrapper<Common> queryWrapper = new QueryWrapper<>();
        /* type = 11 对应学历的字典 */
        queryWrapper.eq("type", 2);
        List<Common> commonList = commonMapper.selectList(queryWrapper);
        Map<Integer, Common> commonMap = new HashMap<>(10);
        commonList.forEach((item) -> commonMap.put(item.getId(), item));

        /* 入住状态id为112为已退住 */
        int totalElder = Math.toIntExact(checkRecordMapper.selectCount(new LambdaQueryWrapper<CheckRecord>()
                .ne(CheckRecord::getInStatusId, 112)));
        int totalNursingHome = Math.toIntExact(nursingHomeMapper.selectCount(null));
        int totalEmployee = employeeMapper.queryEmployeeCount(null);
        int totalEquipment = equipmentMapper.queryEquipmentCount(null);
        int totalBerth = berthMapper.getBerthCount(null);
        int totalFreeBerth = Math.toIntExact(berthMapper.selectCount(new LambdaQueryWrapper<Berth>().isNull(Berth::getElderId)));

        int consultOfDay = Math.toIntExact(consultMapper.selectCount(new LambdaQueryWrapper<ConsultRecord>()
                .eq(ConsultRecord::getDate, nowDate)));
        int checkRecordsOfDay = checkRecordMapper.getCheckRecordsCount(daily);
        int outRecordsOfDay = Math.toIntExact(outRecordMapper.selectCount(new LambdaQueryWrapper<OutRecord>()
                .eq(OutRecord::getOutDate, nowDate)));
        int visitsOfDay = visitMapper.getVisitCount(daily);
        int complaintsOfDay = complaintMapper.getComplaintsCount(daily);
        int complaintsOfWeek = complaintMapper.getComplaintsCount(weekly);
        int complaintsOfMonth = complaintMapper.getComplaintsCount(monthly);

        QueryWrapper<Employee> employeeQueryWrapper = new QueryWrapper<>();
        employeeQueryWrapper.groupBy("education_id");
        employeeQueryWrapper.select("education_id, count(*) as total");
        List<Map<String, Object>> employeeMapList = employeeMapper.selectMaps(employeeQueryWrapper);
        Map<String, Integer> employeeEducation = new HashMap<>(10);
        employeeMapList.forEach(item -> employeeEducation.put(commonMap.get(Integer.parseInt(item.get("education_id").toString())).getName(),
                Integer.parseInt(item.get("total").toString())));
        /* 不存在的学历层次补0 */
        commonList.forEach(common -> employeeEducation.putIfAbsent(common.getName(), 0));

        /* 退住记录统计 */
        int retardCountOfDay = retardRecordMapper.getRetardRecordsCount(daily);
        int retardCountOfWeek = retardRecordMapper.getRetardRecordsCount(weekly);
        int retardCountOfMonth = retardRecordMapper.getRetardRecordsCount(monthly);
        /* 入住记录统计 */
        int checkCountOfDay = checkRecordMapper.getCheckRecordsCount(daily);
        int checkCountOfWeek = checkRecordMapper.getCheckRecordsCount(weekly);
        int checkCountOfMonth = checkRecordMapper.getCheckRecordsCount(monthly);

        /* 获取退住评价平均分 */
        QueryWrapper<RetardRecord> retardRecordQueryWrapper = new QueryWrapper<>();
        retardRecordQueryWrapper.select("avg(evaluation) as avg_score");
        List<Map<String, Object>> maps = retardRecordMapper.selectMaps(retardRecordQueryWrapper);
        float retardAverageScore = Float.parseFloat(maps.get(0).get("avg_score").toString());

        /* 获取退住评价各个分数段分布 */
        retardRecordQueryWrapper.clear();
        retardRecordQueryWrapper.groupBy("evaluation").select("evaluation, count(*) as total");
        List<Map<String, Object>> retardScores = retardRecordMapper.selectMaps(retardRecordQueryWrapper);
        Map<Float, Integer> retardEvaluation = new TreeMap<>();
        retardScores.forEach(retardScore -> retardEvaluation.put(Float.parseFloat(retardScore.get("evaluation").toString()),
                Integer.parseInt(retardScore.get("total").toString())));
        /* 不存在的分数段补0 */
        float maxScore = 5f, diff = 0.5f;
        for (float score = 0; score <= maxScore; score = score + diff) {
            retardEvaluation.putIfAbsent(score, 0);
        }

        Map<String, Object> total = new HashMap<>(10);
        total.put("elders", totalElder);
        total.put("employees", totalEmployee);
        total.put("equipments", totalEquipment);
        total.put("nursingHomes", totalNursingHome);
        total.put("berths", totalBerth);
        total.put("freeBerths", totalFreeBerth);
        Map<String, Object> day = new HashMap<>(4);
        day.put("retardCount", retardCountOfDay);
        day.put("checkCount", checkCountOfDay);
        day.put("complaints", complaintsOfDay);
        day.put("consults", consultOfDay);
        day.put("checkRecords", checkRecordsOfDay);
        day.put("outRecords", outRecordsOfDay);
        day.put("visits", visitsOfDay);
        Map<String, Object> week = new HashMap<>(4);
        week.put("retardCount", retardCountOfWeek);
        week.put("checkCount", checkCountOfWeek);
        week.put("complaints", complaintsOfWeek);
        Map<String, Object> month = new HashMap<>(4);
        month.put("retardCount", retardCountOfMonth);
        month.put("checkCount", checkCountOfMonth);
        month.put("complaints", complaintsOfMonth);
        return BigScreenResponseBody.builder()
                .daily(day)
                .weekly(week)
                .monthly(month)
                .total(total)
                .employeeEducation(employeeEducation)
                .retardAverageScore(retardAverageScore)
                .retardEvaluation(retardEvaluation)
                .build();
    }

    /**
     * 获取当前日期前一周的日期
     *
     * @return 格式化为 yyyy-MM-dd 的一周前的日期
     */
    public String getWeekAgoDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_WEEK, -7);
        return FormatDate.getFormatDate(calendar.getTime());
    }

    /**
     * 获取当前日期的前一个月的日期
     *
     * @return 格式化为 yyyy-MM-dd 的一个月前的日期
     */
    public String getMonthAgoDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1);
        return FormatDate.getFormatDate(calendar.getTime());
    }
}
